﻿using System;
using System.Linq;
using System.Net;
using System.Net.Mail;
using System.Text;
using System.Web.Mvc;
using CultuRAM.DAL;
using CultuRAM.Models;
using PagedList;
using WebMatrix.WebData;
using Twilio;


namespace CultuRAM.Controllers
{
    [Authorize]
    public class AccreditingRequestController : Controller
    {

        private readonly UnitOfWork _unitOfWork = new UnitOfWork();

        //
        // GET: /AccreditingRequest/

        public ActionResult Index(int? page)
        {
            var accResquests = _unitOfWork.AccResquestRepository.Get();
            //var accResquests = from s in _unitOfWork.AccResquestRepository.GetList() select s;
            
            if (Request.HttpMethod == "GET")
            {
            }
            else
            {
                page = 1;
            }

            int pageSize = 7;
            int pageNumber = (page ?? 1);


            return View(accResquests.OrderByDescending(o => o.RequestDate).ToPagedList(pageNumber, pageSize));
        }

        //
        // GET: /AccreditingRequest/Create
        [AllowAnonymous]
        public ActionResult Create()
        {
            PopulateCityDropDownList();
            PopulateEntityTypeDropDownList();
            return View();
        }

        
        //
        // POST: /AccreditingRequest/Create
        [AllowAnonymous]
        [HttpPost]
        public ActionResult Create(Entity entity)
        {
            if (ModelState.IsValid)
            {
                _unitOfWork.EntityRepository.Insert(entity);
                _unitOfWork.Save();

                var codNum = 1;
                if (_unitOfWork.AccResquestRepository.GetList().Count != 0)
                {
                    codNum = _unitOfWork.AccResquestRepository.GetList().Last().AccReqId + 1;
                }
   
                var reqCode = CreateReqCode(5) + codNum;
                StringBuilder senha = new StringBuilder(5);

                //Accreditation Request Registration
                var accReq = new AccreditingRequest()
                {            
                    RequestCode = reqCode,
                    RequestDate = DateTime.Now,
                    FeedbackDate = DateTime.Now,
                    AccreditingState = _unitOfWork.AccStateRepository.GetByID(1),
                    Entity = _unitOfWork.EntityRepository.GetByID(entity.EntityId),
                    UserId = WebSecurity.CurrentUserId
                };

                _unitOfWork.AccResquestRepository.Insert(accReq);
                _unitOfWork.Save();
                
                
                var urlBase = "http://" + Request.Url.Authority + Request.Url.Segments[0];
                urlBase = urlBase.Remove(urlBase.Length - 1);

                //Send EMAIL
                var fromEmail = "CultuRAM <verc04@gmail.com>";
                var toEmail = accReq.Entity.Email;
                var subjectString = "Pedido de Adesão";
                var bodyString = "Ex.mo(a) Sr.(a)<br>" +
                                 "<b>" + accReq.Entity.Responsible + "</b><br><br> " +
                                 "O pedido de adesão da entidade '<b>" + accReq.Entity.Name + "</b>' " +
                                 "na agenda de eventos CultuRAM foi registado com Sucesso! <br>" +
                                 "O seu pedido será sujeito a análise e em breve receberá a resposta via e-mail e " +
                                 "SMS caso tenha introduzido um número de telemóvel.<br><br>" +
                                 "Código do Pedido de Adesão: <b><a href='" + 
                                 urlBase + Url.Action("AccStatus", "Home", new { code = accReq.RequestCode }) + "'>" + 
                                 accReq.RequestCode + "</a></b> (Utilize este código para consultar o estado do seu pedido.) <br><br>" + 
                                 "Com os melhores cumprimentos, <br>Administração da CultuRAM";

                if (!String.IsNullOrEmpty(accReq.Entity.Email)) 
                    SendEmail(fromEmail, toEmail, subjectString, bodyString, accReq); 
  

                //Send SMS
                var phoneTo = "+351" + entity.CellPhone;
                var smsString = "O pedido de adesão da entidade " + accReq.Entity.Name +
                                " na agenda de eventos CultuRAM foi registado com Sucesso! " +
                                "Código: " + accReq.RequestCode + " (Utilize este código para consultar o estado do seu pedido.)";
                if (!String.IsNullOrEmpty(entity.CellPhone)) 
                    SendSms(phoneTo, smsString);

                return RedirectToAction("AccReplay", "Home", new { @id = accReq.AccReqId });
            }


            PopulateCityDropDownList(entity.CityId);
            PopulateEntityTypeDropDownList(entity.EntityTypeId);
            return View(entity);
        }


        //
        // GET: /AccreditingRequest/Edit/5

        public ActionResult Edit(int id = 0)
        {
            var accReq = _unitOfWork.AccResquestRepository.GetByID(id);
            if (accReq == null)
            {
                return HttpNotFound();

            }

            PopulateEntityDropDownList(accReq.EntityId);
            PopulateUserDropDownList(accReq.UserId);
            PopulateAccReqStateDropDownList(accReq.AccReqId);
            return View(accReq);
        }

        //
        // POST: /AccreditingRequest/Edit/5

        [HttpPost]
        public ActionResult Edit(AccreditingRequest accReq)
        {
            if (ModelState.IsValid)
            {

                _unitOfWork.AccResquestRepository.Update(accReq);
                _unitOfWork.Save();
                return RedirectToAction("Index");
            }

            PopulateEntityDropDownList(accReq.EntityId);
            PopulateUserDropDownList(accReq.UserId);
            PopulateAccReqStateDropDownList(accReq.AccReqId);
            return View(accReq);
        }


        //
        // GET: /AccreditingRequest/Delete/5

        public ActionResult Delete(int id = 0)
        {
            var entity = _unitOfWork.AccResquestRepository.GetByID(id);
            if (entity == null)
            {
                return HttpNotFound();
            }
            return View(entity);
        }

        //
        // POST: /AccreditingRequest/Delete/5

        [HttpPost, ActionName("Delete")]
        public ActionResult DeleteConfirmed(int id)
        {
            var entity = _unitOfWork.AccResquestRepository.GetByID(id);
            _unitOfWork.AccResquestRepository.Delete(entity);
            _unitOfWork.Save();
            return RedirectToAction("Index");
        }

        protected override void Dispose(bool disposing)
        {
            _unitOfWork.Dispose();
            base.Dispose(disposing);
        }



        //AUXILIARY METHODS /////////////////////////////////////////////////////////

        //Method: Populate the DropDownList of Entity Type
        private void PopulateEntityTypeDropDownList(int? selectedEntityTypeId = 0)
        {
            if (selectedEntityTypeId == null)
            {
                var entityTypes = _unitOfWork.EntityTypeRepository.Get().ToList();
                ViewBag.EntityTypeId = new SelectList(entityTypes, "EntityTypeId", "EntityTypeName");
            }
            else
            {
                var entityTypes = _unitOfWork.EntityTypeRepository.Get().ToList();
                ViewBag.EntityTypeId = new SelectList(entityTypes, "EntityTypeId", "EntityTypeName", selectedEntityTypeId);
            }
        }

        //Method: Populate the DropDownList of City
        private void PopulateCityDropDownList(int? selectedCityId = 0)
        {
            if (selectedCityId == null)
            {
                var cities = _unitOfWork.CityRepository.Get().ToList();
                ViewBag.CityId = new SelectList(cities, "CityId", "CityName");
            }
            else
            {
                var cities = _unitOfWork.CityRepository.Get().ToList();
                ViewBag.CityId = new SelectList(cities, "CityId", "CityName", selectedCityId);
            }
        }

        //Method: Populate the DropDownList of Accrediting Request State
        private void PopulateAccReqStateDropDownList(int? selectedAccStateId = null)
        {
            if (selectedAccStateId == null)
            {
                var accReqState = _unitOfWork.AccStateRepository.GetList();
                ViewBag.AccStateId = new SelectList(accReqState, "AccStateId", "AccState");
            }
            else
            {
                var accReqState = _unitOfWork.AccStateRepository.GetList();
                ViewBag.AccStateId = new SelectList(accReqState, "AccStateId", "AccState", selectedAccStateId);
            }
        }

        //Method: Populate the DropDownList of User
        private void PopulateUserDropDownList(int? selectedUserId = null)
        {
            if (selectedUserId == null)
            {
                var user = _unitOfWork.UserProfileRepository.GetList();
                ViewBag.UserId = new SelectList(user, "UserId", "UserName");
            }
            else
            {
                var user = _unitOfWork.UserProfileRepository.GetList();
                ViewBag.UserId = new SelectList(user, "UserId", "UserName", selectedUserId);
            }
        }

        //Method: Populate the DropDownList of User
        private void PopulateEntityDropDownList(int? selectedEntityId = null)
        {
            if (selectedEntityId == null)
            {
                var entity = _unitOfWork.EntityRepository.GetList();
                ViewBag.EntityId = new SelectList(entity, "EntityId", "Name");
            }
            else
            {
                var entity = _unitOfWork.EntityRepository.GetList();
                ViewBag.EntityId = new SelectList(entity, "EntityId", "Name", selectedEntityId);
            }
        }

        //Generate Code of the Accrediting Request
        public string CreateReqCode(int size)
        {
            const string caracteresValidos = "abcdefghijklmnopqrstuvwxyz";
            int maxValue = caracteresValidos.Length;
            Random random = new Random(DateTime.Now.Millisecond);
            StringBuilder code = new StringBuilder(size);

            for (int indice = 0; indice < size; indice++)
                code.Append(caracteresValidos[random.Next(0, maxValue)]);

            return code.ToString().ToUpper();
        }

        //Send Email Menssage
        public String SendEmail(string from, string to, string subject, string body, AccreditingRequest accReq)
        {

            var mail = new MailMessage(from, to);
            var smtp = new SmtpClient();
            String msg;

            try
            {
                mail.Subject = subject;
                mail.Body = body;
                mail.IsBodyHtml = true;
                mail.From = new MailAddress(from);
                //m.To.Add(new MailAddress(To));
               
                smtp.Host = "smtp.gmail.com";   // We use gmail as our smtp client
                smtp.Port = 587;
                smtp.EnableSsl = true;
                smtp.UseDefaultCredentials = true;
                smtp.Credentials = new NetworkCredential("geral.culturam@gmail.com", "cultur@m");             
                smtp.Send(mail);

                msg = "Successful";

            }
            catch (Exception)
            {
                msg = "Error";         
            }

            return msg;
        }

        //Send Email Menssage
        public bool SendSms(string phoneTo, string smsString)
        {

            const string accountSid = "AC9486809b7220f77eb74bc8bc0b05cae6";
            const string authToken = "8d420deb9e59937c0113f75fb419baa5";

            try
            {
                var client = new TwilioRestClient(accountSid, authToken);
       
                client.SendSmsMessage("(980) 365-8354", phoneTo, smsString);
                
                return true;
            }

            catch (Exception)
            {
                return false;
            }

        }

    }
}
